package com.sayice.robotconflict.service;

import cn.hutool.core.bean.BeanUtil;
import com.sayice.robotconflict.entity.FriendReqEntity;
import com.sayice.robotconflict.entity.PlayerEntity;
import com.sayice.robotconflict.entity.SocialEntity;
import com.sayice.robotconflict.entity.SocialPlayerEntity;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * 社交信息业务处理
 *
 * @author shubing
 */
@Slf4j
@Service
public class SocialService {
    @Autowired
    private MongoTemplate mongoTemplate;
    
    /**
     * 根据玩家名查询玩家，使用模糊查询
     *
     * @param name 玩家名
     */
    public List<SocialPlayerEntity> queryPlayersByName(String name) {
        log.info("SocialService queryPlayersByName name={}", name);
        Query query = Query.query(Criteria.where("name").regex("^.*" + name + ".*$"));
        query.fields().include("name");
        List<PlayerEntity> playerEntities = mongoTemplate.find(query, PlayerEntity.class);
        return BeanUtil.copyToList(playerEntities, SocialPlayerEntity.class);
    }
    
    /**
     * 根据玩家名查询玩家并过滤掉指定的玩家，使用模糊查询
     *
     * @param name       玩家名
     * @param exceptedId 需要过滤的玩家ID
     */
    public List<SocialPlayerEntity> queryPlayersByNameExcept(String name, String exceptedId) {
        log.info("SocialService queryPlayersByNameExcept name={}, exceptedId={}", name, exceptedId);
        Query query = Query.query(Criteria.where("_id").ne(exceptedId).and("name").regex("^.*" + name + ".*$"));
        query.fields().include("name");
        List<PlayerEntity> playerEntities = mongoTemplate.find(query, PlayerEntity.class);
        return BeanUtil.copyToList(playerEntities, SocialPlayerEntity.class);
    }
    
    /**
     * 查询好友列表
     *
     * @param playerId 玩家ID
     */
    public List<SocialPlayerEntity> queryFriends(String playerId) {
        log.info("SocialService queryFriends playerId={}", playerId);
        Query query = Query.query(Criteria.where("playerId").is(playerId));
        query.fields().include("friends");
        SocialEntity socialEntity = mongoTemplate.findOne(query, SocialEntity.class);
        return Optional.ofNullable(socialEntity).map(SocialEntity::getFriends).orElse(Collections.emptyList());
    }
    
    /**
     * 添加好友
     *
     * @param id1 玩家1 ID
     * @param id2 玩家2 ID
     */
    public void addFriend(String id1, String id2) {
        log.info("SocialService addFriend id1={}, id2={}", id1, id2);
        PlayerEntity playerEntity1 = mongoTemplate.findById(id1, PlayerEntity.class);
        PlayerEntity playerEntity2 = mongoTemplate.findById(id2, PlayerEntity.class);
        if (playerEntity1 == null || playerEntity2 == null) {
            return;
        }
        SocialPlayerEntity socialPlayerEntity1 = BeanUtil.copyProperties(playerEntity1, SocialPlayerEntity.class);
        SocialPlayerEntity socialPlayerEntity2 = BeanUtil.copyProperties(playerEntity2, SocialPlayerEntity.class);
        // 添加玩家2到玩家1的好友列表
        Query query = Query.query(Criteria.where("playerId").is(id1));
        Update update = new Update().addToSet("friends", socialPlayerEntity2);
        mongoTemplate.updateFirst(query, update, SocialEntity.class);
        // 添加玩家1到玩家2的好友列表
        query = Query.query(Criteria.where("playerId").is(id2));
        update = new Update().addToSet("friends", socialPlayerEntity1);
        mongoTemplate.updateFirst(query, update, SocialEntity.class);
    }
    
    /**
     * 删除好友
     *
     * @param id1 玩家1 ID
     * @param id2 玩家2 ID
     */
    public void deleteFriend(String id1, String id2) {
        log.info("SocialService deleteFriend id1={}, id2={}", id1, id2);
        // 将玩家2从玩家1的好友列表中删除
        Query query = Query.query(Criteria.where("playerId").is(id1));
        Update update = new Update().pull("friends", new Document("id", id2));
        mongoTemplate.updateFirst(query, update, SocialEntity.class);
        // 将玩家1从玩家2的好友列表中删除
        query = Query.query(Criteria.where("playerId").is(id2));
        update = new Update().pull("friends", new Document("id", id1));
        mongoTemplate.updateFirst(query, update, SocialEntity.class);
    }
    
    /**
     * 查询好友申请列表
     *
     * @param playerId 玩家ID
     */
    public List<FriendReqEntity> queryFriendReqs(String playerId) {
        log.info("SocialService queryFriendReqs playerId={}", playerId);
        Query query = Query.query(Criteria.where("playerId").is(playerId));
        query.fields().include("friendReqs");
        SocialEntity socialEntity = mongoTemplate.findOne(query, SocialEntity.class);
        return Optional.ofNullable(socialEntity).map(SocialEntity::getFriendReqs).orElse(Collections.emptyList());
    }
    
    /**
     * 是否存在好友申请
     *
     * @param playerId 玩家ID
     * @param fromId   发起申请的玩家ID
     */
    public boolean existsFriendReq(String playerId, String fromId) {
        log.info("SocialService existsFriendReq playerId={}, fromId={}", playerId, fromId);
        Query query = Query.query(Criteria.where("playerId").is(playerId));
        query.fields().include("friendReqs");
        SocialEntity socialEntity = mongoTemplate.findOne(query, SocialEntity.class);
        return socialEntity != null && socialEntity.getFriendReqs().stream()
                .anyMatch(it -> it.getFrom().getId().equals(fromId));
    }
    
    /**
     * 添加好友申请
     *
     * @param playerId 玩家ID
     * @param fromId   发起申请的玩家ID
     */
    public void addFriendReq(String playerId, String fromId) {
        log.info("SocialService addFriendReq playerId={}, fromId={}", playerId, fromId);
        PlayerEntity fromPlayerEntity = mongoTemplate.findById(fromId, PlayerEntity.class);
        SocialPlayerEntity socialFromPlayerEntity = BeanUtil.copyProperties(fromPlayerEntity, SocialPlayerEntity.class);
        FriendReqEntity friendReqEntity = new FriendReqEntity(socialFromPlayerEntity);
        Query query = Query.query(Criteria.where("playerId").is(playerId));
        Update update = new Update().addToSet("friendReqs", friendReqEntity);
        mongoTemplate.updateFirst(query, update, SocialEntity.class);
    }
    
    /**
     * 修改好友申请为已读
     *
     * @param playerId 玩家ID
     * @param fromId   发起申请的玩家ID
     */
    public void readFriendReq(String playerId, String fromId) {
        log.info("SocialService readFriendReq playerId={}, fromId={}", playerId, fromId);
        Query query = Query.query(Criteria.where("playerId").is(playerId)
                .and("friendReqs.from.id").is(fromId));
        Update update = new Update().set("friendReqs.$.read", true);
        mongoTemplate.updateFirst(query, update, SocialEntity.class);
    }
    
    /**
     * 删除好友申请
     *
     * @param playerId 玩家ID
     * @param fromId   发起申请的玩家ID
     */
    public void deleteFriendReq(String playerId, String fromId) {
        log.info("SocialService deleteFriendReq playerId={}, fromId={}", playerId, fromId);
        Query query = Query.query(Criteria.where("playerId").is(playerId));
        Update update = new Update().pull("friendReqs", new Document("from.id", fromId));
        mongoTemplate.updateFirst(query, update, SocialEntity.class);
    }
}
